<script setup lang="ts">
import type { InfraCodegenApi } from '#/api/infra/codegen';

import { onMounted, ref, watch } from 'vue';

import formCreate from '@form-create/ant-design-vue';
import FcDesigner from '@form-create/antd-designer';
import { Button, message, Modal } from 'ant-design-vue';

import { useFormCreateDesigner } from '#/components/form-create';

defineOptions({ name: 'FormBuilder' });

interface Props {
  table: InfraCodegenApi.CodegenTable;
  columns: InfraCodegenApi.CodegenColumn[];
}

const props = defineProps<Props>();
const emit = defineEmits(['form-change']);

const designer = ref(); // 表单设计器

// 表单设计器配置
const designerConfig = ref({
  switchType: [],
  autoActive: true,
  useTemplate: false,
  formOptions: {
    form: {
      labelWidth: '100px',
    },
  },
  fieldReadonly: false,
  hiddenDragMenu: false,
  hiddenDragBtn: false,
  hiddenMenu: [],
  hiddenItem: [],
  hiddenItemConfig: {},
  disabledItemConfig: {},
  showSaveBtn: false,
  showConfig: true,
  showBaseForm: true,
  showControl: true,
  showPropsForm: true,
  showEventForm: true,
  showValidateForm: true,
  showFormConfig: true,
  showInputData: true,
  showDevice: true,
  appendConfigData: [],
});

const dialogVisible = ref(false);
const dialogTitle = ref('');
const formData = ref('');

useFormCreateDesigner(designer);

/** 根据htmlType获取表单组件类型 */
function getFormComponentTypeByHtmlType(column: InfraCodegenApi.CodegenColumn) {
  const htmlType = column.htmlType || 'input';
  
  switch (htmlType) {
    case 'input':
      return {
        type: 'input',
        dragTag: 'input',
      };
    case 'textarea':
      return {
        type: 'input',
        dragTag: 'textarea',
        props: {
          type: 'textarea',
        },
      };
    case 'select':
      return {
        type: 'select',
        dragTag: 'select',
        options: [
          { label: '选项01', value: '1' },
          { label: '选项02', value: '2' },
          { label: '选项03', value: '3' },
        ],
      };
    case 'radio':
      return {
        type: 'radio',
        dragTag: 'radio',
        options: [
          { label: '选项01', value: '1' },
          { label: '选项02', value: '2' },
          { label: '选项03', value: '3' },
        ],
      };
    case 'checkbox':
      return {
        type: 'checkbox',
        dragTag: 'checkbox',
        options: [
          { label: '选项01', value: '1' },
          { label: '选项02', value: '2' },
          { label: '选项03', value: '3' },
        ],
      };
    case 'datetime':
      return {
        type: 'DatePicker',
        dragTag: 'DatePicker',
        props: {
          showTime: true,
          format: 'YYYY-MM-DD HH:mm:ss',
        },
      };
    case 'editor':
      return {
        type: 'fcEditor',
        dragTag: 'fcEditor',
      };
    case 'imageUpload':
      return {
        type: 'upload',
        dragTag: 'upload',
        props: {
          action: '/admin-api/infra/file/upload',
          listType: 'picture-card',
          accept: 'image/*',
          multiple: false
        },
      };
    case 'fileUpload':
      return {
        type: 'upload',
        dragTag: 'upload',
        props: {
          action: '/admin-api/infra/file/upload',
          multiple: false
        },
      };
    default:
      return {
        type: 'input',
        dragTag: 'input',
      };
  }
}

/** 根据数据库字段生成表单规则 */
function generateFormRules(columns: InfraCodegenApi.CodegenColumn[]) {
  const rules: any[] = [];

  // 过滤出允许创建或更新的字段
  const editableColumns = columns.filter(
    (col) =>
      (col.createOperation === true || col.updateOperation === true) &&
      !isSystemField(col.javaField || col.columnName),
  );

  editableColumns.forEach((col) => {
    const fieldName = col.javaField || col.columnName;
    const fieldTitle = col.columnComment || fieldName;
    const componentType = getFormComponentTypeByHtmlType(col);
    
    // 生成唯一的ID和name
    const uniqueId = `field_${fieldName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const fcId = `id_${uniqueId}`;
    const refName = `ref_${uniqueId}`;
    
    const rule: any = {
      type: componentType.type,
      field: fieldName,
      title: fieldTitle,
      info: '',
      $required: !col.nullable,
      _fc_id: fcId,
      name: refName,
      display: true,
      hidden: false,
      _fc_drag_tag: componentType.dragTag,
    };

    // 添加组件特定的属性
    if (componentType.props) {
      rule.props = { ...componentType.props };
    }

    // 添加选项数据（对于radio、checkbox、select等）
    if (componentType.options) {
      rule.options = componentType.options;
    }

    // 添加effect（对于有选项的组件）
    if (['radio', 'checkbox', 'select'].includes(componentType.type)) {
      rule.effect = { fetch: '' };
    }

    rules.push(rule);
  });

  return rules;
}

/** 判断是否为系统字段 */
function isSystemField(fieldName: string): boolean {
  const systemFields = [
    'id',
    'createTime',
    'updateTime',
    'createBy',
    'updateBy',
    'creator',
    'updater',
    'createUser',
    'updateUser',
    'deleted',
  ];
  return systemFields.includes(fieldName);
}

/** 监听表单变化 */
function onFormChange() {
  if (designer.value) {
    const rule = designer.value.getRule();
    const option = designer.value.getOption();

    // 通知父组件表单配置发生变化
    emit('form-change', {
      rule,
      option,
      json: formCreate.toJson(rule),
    });
  }
}

/** 生成 JSON */
function showJson() {
  dialogVisible.value = true;
  dialogTitle.value = '生成 JSON';
  formData.value = JSON.stringify(designer.value.getRule(), null, 2);
}

/** 获取表单配置（供父组件调用） */
function getFormConfig() {
  if (designer.value) {
    const rule = designer.value.getRule();
    const option = designer.value.getOption();
    return {
      rule,
      option,
      json: formCreate.toJson(rule),
    };
  }
  return null;
}

/** 设置表单配置（供父组件调用） */
function setFormConfig(config: any) {
  if (designer.value && config && config.rule) {
    designer.value.setRule(config.rule);
  }
}

/** 自动生成表单（供父组件调用） */
function autoGenerateForm(columns: InfraCodegenApi.CodegenColumn[]) {
  if (designer.value && columns) {
    const rules = generateFormRules(columns);
    if (rules.length > 0) {
      designer.value.setRule(rules);
      // 触发表单变化事件
      setTimeout(() => {
        onFormChange();
      }, 100);
    }
  }
}

/** 手动重新构建表单 */
function rebuildForm() {
  Modal.confirm({
    title: '确认重新构建表单',
    content: '此操作将根据当前字段信息重新生成表单，现有的表单设计将被覆盖，是否继续？',
    okText: '确定',
    cancelText: '取消',
    onOk: () => {
      if (props.columns && props.columns.length > 0) {
        const rules = generateFormRules(props.columns);
        if (rules.length > 0) {
          designer.value?.setRule(rules);
          setTimeout(() => {
            onFormChange();
          }, 100);
          message.success('表单重新构建完成');
        } else {
          message.warn('没有找到可构建的字段');
        }
      } else {
        message.warn('字段信息为空，无法构建表单');
      }
    }
  });
}

// 暴露方法给父组件
defineExpose({
  getFormConfig,
  setFormConfig,
  onFormChange,
  autoGenerateForm,
  rebuildForm,
});

// 监听props变化，自动生成表单
watch(
  [() => props.table, () => props.columns],
  () => {
    // 检查tableForm是否为空，如果为空则自动生成
    const hasEmptyForm = !props.table.tableForm || 
                        props.table.tableForm.trim() === '' || 
                        props.table.tableForm === '{\n}';
    
    if (hasEmptyForm && props.columns && props.columns.length > 0) {
      setTimeout(() => {
        autoGenerateForm(props.columns);
      }, 500);
    }
  },
  { deep: true, immediate: true }
);

/** 初始化 */
onMounted(async () => {
  // 延迟初始化，确保designer已经加载
  setTimeout(() => {
    if (props.table.tableForm && props.table.tableForm !== '{\n}') {
      try {
        const config = JSON.parse(props.table.tableForm);
        if (config.rule && config.rule.length > 0) {
          setFormConfig(config);
        } else {
          // 如果解析出来的rule为空，也自动生成
          autoGenerateForm(props.columns);
        }
      } catch (error) {
        console.warn('解析表单构建器配置失败:', error);
        autoGenerateForm(props.columns);
      }
    } else {
      autoGenerateForm(props.columns);
    }
  }, 800);
});
</script>

<template>
  <div class="form-builder-container">
    <FcDesigner
      ref="designer"
      height="70vh"
      :config="designerConfig"
      @change="onFormChange"
    >
      <template #handle>
        <Button size="small" type="primary" ghost @click="showJson">
          查看JSON
        </Button>
      </template>
    </FcDesigner>

    <!-- 弹窗：代码预览 -->
    <Modal
      v-model:open="dialogVisible"
      :title="dialogTitle"
      :footer="false"
      width="800px"
      :destroy-on-close="true"
    >
      <div>
        <div class="mt-4">
          <pre><code class="hljs json">{{ formData }}</code></pre>
        </div>
      </div>
    </Modal>
  </div>
</template>

<style scoped>
.form-builder-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.hljs {
  padding: 16px;
  border-radius: 6px;
  background-color: #f6f8fa;
  font-size: 14px;
  line-height: 1.45;
  overflow-x: auto;
}
</style>